﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace SurvivalStrategy.PathFinding
{
    class PathNode
    {
        private List<PathNode> neighbourNodes;                      //wezly sasiednie
        public List<PathNode> NeighbourNodes { get {return neighbourNodes; } }

        public Vector2 Position { get; internal set; }             //pozycja wezla
        private float visitWeight;                                  //aktualna waga odwiedzin

        private static float VISIT_DELTA = 5f;                    //przyrost w razie odwiedzin
        private static float VISIT_MAX = 100;                         //maksymalna waga odwiedzin
        private static float RADIUS = 50;                           //maksymalna odleglosc od sasiada
        private static float DEG_TO_RAD = (float)(Math.PI / 180);   //zmienna pomocnicza przy rzutowaniu katow ze stopni na radiany
        private static float ACCEPTABLE_DISTANCE = 35;              //minimalna odleglosc pomiedzy punktami
        private static int ANGLE_NUMBER = 5;                       //miara w katach co ile ma probkowac kolejne punkty

        public int Cost { get; set; }
        public int Heuristic { get; set; }
        public int Value
        {
            get { return Cost + Heuristic + (int)visitWeight; }
        }

        private PathMap pathMap;                                    //pathMap do ktorego nalezy dany node

        public PathNode(PathMap pathMap, Vector2 position)
        {
            this.pathMap = pathMap;
            this.Position = position;
            neighbourNodes = new List<PathNode>();
            visitWeight = 0;

            SetNeighbours();
        }

        public PathNode(PathMap pathMap)
        {
            this.pathMap = pathMap;
            neighbourNodes = new List<PathNode>();
            visitWeight = 0;
        }

        public void Visit()
        {
            if (visitWeight == 0)
                AddNewNodes();
            visitWeight = visitWeight < VISIT_MAX ? visitWeight + VISIT_DELTA : visitWeight = VISIT_MAX;
        }

        private void SetNeighbours()
        {
            neighbourNodes.Clear();
            foreach (PathNode node in pathMap.Nodes.Values)
                if(node != this)
                    if(Vector2.Distance(this.Position, node.Position) <= RADIUS)
                        neighbourNodes.Add(node);
        }

        private void AddNewNodes()
        {
            double angleAddition = 360 / (double)ANGLE_NUMBER;

            double r = RADIUS - 10;
            for (int i = 0; i <= ANGLE_NUMBER; i++)
            {
                double angle = angleAddition * i;
                int x = (int)((Math.Cos(angle * DEG_TO_RAD) * r) + this.Position.X);
                int y = (int)((Math.Sin(angle * DEG_TO_RAD) * r) + this.Position.Y);

                Vector2 newPoint = new Vector2(x, y);

                bool add = true;
                foreach (PathNode p in neighbourNodes)
                    if (Vector2.Distance(p.Position, newPoint) < ACCEPTABLE_DISTANCE)
                        add = false;
                if (add)
                {
                    //sprawdza czy w podanym miejscu nie ma przeszkody
                    Rectangle newRectangle = new Rectangle((int)newPoint.X, (int)newPoint.Y, 5, 5);
                    
                    pathMap.AddNode(newPoint);
                    neighbourNodes.Add(pathMap.Nodes[newPoint]);
                }
            }
        }
    }
}
